"""
代码编写Agent
继承自TaskOrientedAgent，专门处理代码相关任务
"""

import os
import re
import json
from typing import Dict, Any, List, Optional
from core.base_agent import TaskOrientedAgent


class CodeToolsRegistry:
    """代码专用工具注册器"""
    
    def __init__(self):
        from tools.toolsregistry import ToolsRegistry
        self.tools = ToolsRegistry()
        self._load_code_tools_()
        self._load_external_code_tools_()
    
    def _load_code_tools_(self):
        """加载代码专用工具"""
        try:
            # 这里可以定义内置的代码工具
            pass
        except Exception as e:
            from tools.utils import EnhancedOutput, OutputType
            EnhancedOutput.display(f"加载内置代码工具失败: {str(e)}", OutputType.ERROR)
    
    def _load_external_code_tools_(self):
        """加载外部的代码工具文件"""
        try:
            import sys
            from pathlib import Path
            
            tools_dir = Path(__file__).parent.parent / "tools"
            
            # 尝试加载codetools.py中的工具
            codetools_path = tools_dir / "codetools.py"
            if codetools_path.exists():
                try:
                    # 动态导入codetools模块
                    sys.path.insert(0, str(tools_dir))
                    
                    from codetools import CodeExecuteTool, CodeValidateTool, CodeFormatTool
                    
                    # 注册代码执行工具
                    execute_tool = CodeExecuteTool()
                    self.tools.registerTool(
                        name=execute_tool.name,
                        description=execute_tool.description,
                        parameters=execute_tool.parameters,
                        func=execute_tool.execute
                    )
                    
                    # 注册代码验证工具
                    validate_tool = CodeValidateTool()
                    self.tools.registerTool(
                        name=validate_tool.name,
                        description=validate_tool.description,
                        parameters=validate_tool.parameters,
                        func=validate_tool.execute
                    )
                    
                    # 注册代码格式化工具
                    format_tool = CodeFormatTool()
                    self.tools.registerTool(
                        name=format_tool.name,
                        description=format_tool.description,
                        parameters=format_tool.parameters,
                        func=format_tool.execute
                    )
                    
                    from tools.utils import EnhancedOutput, OutputType
                    EnhancedOutput.display("外部代码工具加载完成", OutputType.SUCCESS)
                    
                except ImportError as e:
                    from tools.utils import EnhancedOutput, OutputType
                    EnhancedOutput.display(f"导入codetools失败: {str(e)}", OutputType.WARNING)
                except Exception as e:
                    from tools.utils import EnhancedOutput, OutputType
                    EnhancedOutput.display(f"加载外部代码工具失败: {str(e)}", OutputType.ERROR)
                finally:
                    if str(tools_dir) in sys.path:
                        sys.path.remove(str(tools_dir))
            
        except Exception as e:
            from tools.utils import EnhancedOutput, OutputType
            EnhancedOutput.display(f"加载外部代码工具失败: {str(e)}", OutputType.ERROR)
    
    def getTools(self) -> List[Dict]:
        """获取工具列表"""
        return self.tools.getTools()
    
    def toolsPrompt(self) -> str:
        """获取工具提示"""
        return self.tools.toolsPrompt()
    
    def parseToolCalls(self, text: str) -> List[Dict]:
        """解析工具调用"""
        return self.tools.parseToolCalls(text)
    
    def handleToolCalls(self, tool_calls: List[Dict]) -> str:
        """处理工具调用"""
        return self.tools.handleToolCalls(tool_calls)
    
    def executeTool(self, name: str, arguments: Dict) -> Dict[str, Any]:
        """执行工具"""
        return self.tools.executeTool(name, arguments)


class CodeAgent(TaskOrientedAgent):
    """代码编写Agent"""
    
    def __init__(self, config_name: str = "code"):
        self.current_file = None
        self.file_context = {}
        super().__init__(config_name, {"current_file": None})
    
    def chat(self, user_input: str, reset: bool = False) -> str:
        """处理代码相关对话"""
        if reset:
            self.reset_conversation()
        
        # 增强用户输入，添加当前文件上下文
        enhanced_input = user_input
        if self.current_file:
            enhanced_input = f"当前工作文件: {self.current_file}\n\n{user_input}"
        
        self.messages.append({"role": "user", "content": enhanced_input})
        
        try:
            full_response = ""
            for chunk in self.model.chat(self.messages):
                full_response += chunk
            
            # 检查工具调用
            tool_calls = self.parse_tool_calls(full_response)
            
            if tool_calls:
                # 执行工具调用
                tool_result = self.handle_tool_calls(tool_calls)
                
                # 将工具执行结果添加到对话中
                self.messages.append({"role": "assistant", "content": full_response})
                self.messages.append({"role": "user", "content": f"工具执行结果:\n{tool_result}"})
                
                # 获取最终响应
                final_response = ""
                for chunk in self.model.chat(self.messages):
                    final_response += chunk
                
                self.messages.append({"role": "assistant", "content": final_response})
                self.update_memory(user_input, final_response)
                return final_response
            else:
                # 没有工具调用，直接返回响应
                self.messages.append({"role": "assistant", "content": full_response})
                self.update_memory(user_input, full_response)
                return full_response
                
        except Exception as e:
            error_msg = f"{self.name} 对话出错: {str(e)}"
            from tools.utils import EnhancedOutput, OutputType
            EnhancedOutput.display(error_msg, OutputType.ERROR)
            return error_msg
    
    def _get_specialized_tools(self):
        """获取代码专用工具"""
        return CodeToolsRegistry()
    
    def _post_init(self):
        """后初始化"""
        # 确保工具是CodeToolsRegistry类型
        if not isinstance(self.tools, CodeToolsRegistry):
            self.tools = CodeToolsRegistry()
        
        from tools.utils import EnhancedOutput, OutputType
        EnhancedOutput.display(f"代码Agent {self.name} 初始化完成", OutputType.SYSTEM)
        EnhancedOutput.display(f"已加载 {len(self.tools.getTools())} 个代码工具", OutputType.INFO)
    
    def set_current_file(self, file_path: str):
        """设置当前工作文件"""
        self.current_file = file_path
        self.task_context["current_file"] = file_path
        from tools.utils import EnhancedOutput, OutputType
        EnhancedOutput.display(f"设置当前工作文件: {file_path}", OutputType.INFO)
    
    def analyze_file(self, file_path: str) -> Dict[str, Any]:
        """分析文件结构和内容"""
        try:
            result = self.tools.executeTool("code_read", {"file_path": file_path})
            if not result["success"]:
                return {"success": False, "error": result["stderr"]}
            
            content = result["stdout"]
            
            # 提取内容部分（去掉头部的统计信息）
            lines = content.split('\n')
            content_start = -1
            for i, line in enumerate(lines):
                if line.startswith('-' * 10):
                    content_start = i + 1
                    break
            
            actual_content = '\n'.join(lines[content_start:]) if content_start > 0 else content
            
            # 基本分析
            analysis = {
                "success": True,
                "file_path": file_path,
                "content": actual_content,
                "lines": len(actual_content.splitlines()),
                "size": len(actual_content),
                "language": self._detect_language(file_path),
                "imports": self._extract_imports(actual_content, self._detect_language(file_path)),
                "functions": self._extract_functions(actual_content, self._detect_language(file_path)),
                "classes": self._extract_classes(actual_content, self._detect_language(file_path))
            }
            
            return analysis
            
        except Exception as e:
            return {"success": False, "error": f"分析文件失败: {str(e)}"}
    
    def _detect_language(self, file_path: str) -> str:
        """检测文件编程语言"""
        ext = os.path.splitext(file_path)[1].lower()
        language_map = {
            '.py': 'python',
            '.js': 'javascript',
            '.ts': 'typescript',
            '.java': 'java',
            '.cpp': 'cpp',
            '.c': 'c',
            '.cs': 'csharp',
            '.go': 'go',
            '.rs': 'rust',
            '.php': 'php',
            '.rb': 'ruby',
            '.html': 'html',
            '.css': 'css',
            '.json': 'json',
            '.xml': 'xml',
            '.yaml': 'yaml',
            '.yml': 'yaml'
        }
        return language_map.get(ext, 'text')
    
    def _extract_imports(self, content: str, language: str) -> List[str]:
        """提取导入语句"""
        imports = []
        
        if language == 'python':
            import_patterns = [
                r'import\s+([^\n]+)',
                r'from\s+([^\s]+)\s+import'
            ]
        elif language in ['javascript', 'typescript']:
            import_patterns = [
                r'import\s+.*?\s+from\s+[\'"]([^\'"]+)[\'"]',
                r'require\([\'"]([^\'"]+)[\'"]\)'
            ]
        else:
            return imports
        
        for pattern in import_patterns:
            matches = re.findall(pattern, content)
            imports.extend(matches)
        
        return list(set(imports))  # 去重
    
    def _extract_functions(self, content: str, language: str) -> List[str]:
        """提取函数定义"""
        functions = []
        
        if language == 'python':
            pattern = r'def\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\([^)]*\)\s*:'
        elif language in ['javascript', 'typescript']:
            pattern = r'function\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\([^)]*\)\s*{'
        elif language == 'java':
            pattern = r'(?:public|private|protected)?\s*(?:static\s+)?(?:\w+\s+)?([a-zA-Z_][a-zA-Z0-9_]*)\s*\([^)]*\)\s*\{'
        else:
            return functions
        
        matches = re.findall(pattern, content)
        functions.extend(matches)
        
        return functions
    
    def _extract_classes(self, content: str, language: str) -> List[str]:
        """提取类定义"""
        classes = []
        
        if language == 'python':
            pattern = r'class\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*(?:\([^)]*\))?\s*:'
        elif language in ['javascript', 'typescript']:
            pattern = r'class\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*(?:extends\s+[a-zA-Z_][a-zA-Z0-9_]*)?\s*{'
        elif language == 'java':
            pattern = r'(?:public\s+)?class\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*(?:extends\s+[a-zA-Z_][a-zA-Z0-9_]*)?\s*(?:implements\s+[^{]+)?\s*{'
        else:
            return classes
        
        matches = re.findall(pattern, content)
        classes.extend(matches)
        
        return classes
    
    def _extract_task_keywords(self) -> List[str]:
        """提取代码相关的关键词"""
        return [
            "代码", "编程", "函数", "类", "方法", "变量", 
            "bug", "错误", "优化", "重构", "测试", "调试",
            "算法", "数据结构", "设计模式", "架构", "性能",
            "python", "javascript", "java", "cpp", "go", "rust"
        ]